package com.example.opengl.avengine;

import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.opengl.GLES20;
import android.opengl.GLES30;
import android.util.Log;
import android.util.Size;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewTreeObserver;
import androidx.annotation.NonNull;
import com.example.opengl.egl.CustomerGLRender;
import com.example.opengl.egl.EGLSurfaceHolder;
import com.example.opengl.render.video.VideoDrawer;
import org.jetbrains.annotations.NotNull;


import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.ReentrantLock;

import static android.opengl.EGLExt.EGL_RECORDABLE_ANDROID;
import static android.opengl.GLES20.GL_RGBA;
import static android.opengl.GLES20.GL_TEXTURE_2D;
import static android.opengl.GLES20.GL_UNSIGNED_BYTE;


/**
 * 视频引擎
 */
public class AVEngine {


    private static final int PLAY_GAP = 10;//MS
    private static AVEngine gAVEngine;
    private VideoState mVideoState;
    private SurfaceView mSurfaceView;
    private EngineCallback mUpdateCallback, mCompositeCallback;
    private AVComponent mLastVideoComponent;
    private AVComponent mLastAudioComponent;

    private BlockingQueue<Command> mCmdQueue;

    private AVFrame screenFrame;
    private Size mSurfaceViewSize = new Size(1080, 350);

    private CustomerGLRender mRender;

    public void setRender(@NotNull CustomerGLRender render) {
        mRender = render;
    }

    public interface EngineCallback {
        void onCallback(Object... args1);
    }

    private AVEngine() {
        mCmdQueue = new LinkedBlockingQueue<>();
        mVideoState = new VideoState();
    }

    private static class Command {
        public enum Cmd {
            INIT,
            PLAY,
            PAUSE,
            SEEK,
            RELEASE,
            ADD_COM,
            REMOVE_COM,
            CHANGE_COM,
            SURFACE_CREATED,
            SURFACE_CHANGED,
            SURFACE_DESTROYED,
            COMPOSITE,
            RECORD;
        }

        public Cmd cmd;
        public Object args0;
        public Object args1;
        public Object args2;
        public Object args3;
    }

    private static class Clock {
        public float speed = 1.0f;
        public long lastUpdate = -1;
        public long delta = -1;
        public long lastSeekReq = 0;
        public long seekReq = 0;
    }

    //视频核心信息类
    public static class VideoState {

        public enum VideoStatus {
            INIT,
            START,
            PAUSE,
            SEEK,
            RELEASE
        }

        public boolean isInputEOF;
        public boolean isOutputEOF;
        public long displaySwapCount;
        public long seekPositionUS;
        public long videoDuration;
        public long audioDuration;
        public long durationUS;//视频总时长 us
        public int bgColor;
        public int compositeGop;
        public int compositeFrameRate;
        public int compositeAb;
        public int compositeVb;
        public boolean hasAudio;
        public boolean hasVideo;
        public boolean readyAudio;//合成视频用
        public boolean readyVideo;//合成视频用
        public boolean isSurfaceReady;
        public boolean isEdit;//编辑组件状态
        public long drawClock;//需要绘制video
        public int compositeHeight;//默认1080p 可以选择720 360
        public String compositePath;//合成视频路径
        public Size compositeSize;//合成视频目标宽高
        public Size canvasSize;//surface size
        public VideoStatus status;//播放状态
        public String canvasType;
        public Clock videoClock;
        public Clock extClock;
        public Clock audioClock;
        public AVComponent editComponent;
        public final ReentrantLock stateLock = new ReentrantLock();
        public List<AVComponent> tranComponents = new LinkedList<>();//转场
        public List<AVComponent> videoComponents = new LinkedList<>();//视频轨道
        public List<AVComponent> audioComponents = new LinkedList<>();//音频轨道
        //onDrawFrame方法用到的
        public List<AVComponent> drawPagComponents = new LinkedList<>();//需要绘制pag
        public List<AVComponent> drawVideoComponents = new LinkedList<>();//需要绘制video

        public VideoState() {
            reset();
        }

        public void reset() {
            videoClock = new Clock();
            audioClock = new Clock();
            extClock = new Clock();
            drawClock = 0;
            durationUS = 0;
            videoDuration = 0;
            audioDuration = 0;
            isInputEOF = false;
            isOutputEOF = false;
            compositeHeight = 1080;
            displaySwapCount = 0;
            isEdit = false;
            seekPositionUS = Long.MAX_VALUE;
            status = VideoStatus.INIT;
            isSurfaceReady = false;
            drawPagComponents.clear();
            drawVideoComponents.clear();
            tranComponents.clear();
            videoComponents.clear();
            audioComponents.clear();
        }

        public void lock() {
            stateLock.lock();
        }

        public void unlock() {
            stateLock.unlock();
        }

        public List<AVComponent> findComponents(AVComponent.AVComponentType type, long position) {
            List<AVComponent> mTargetComponents = new LinkedList<>();
            mTargetComponents.clear();
            if (type == AVComponent.AVComponentType.AUDIO) {
                lock();
                for (AVComponent component : audioComponents) {
                    if (type == AVComponent.AVComponentType.ALL || (component.getType() == type &&
                            (position == -1 || component.isValid(position)))) {
                        mTargetComponents.add(component);
                    }
                }
                unlock();
            } else {
                lock();
                for (AVComponent component : type == AVComponent.AVComponentType.TRANSACTION ? tranComponents : videoComponents) {
                    if (type == AVComponent.AVComponentType.ALL || (component.getType() == type &&
                            (position == -1 || component.isValid(position)))) {
                        mTargetComponents.add(component);
                    }
                }
                unlock();
            }
            return mTargetComponents;
        }
    }

    public long getCurrentTimeUs() {
        return System.nanoTime() / 1000;
    }

    public void setClock(Clock clock, long time) {
        clock.lastUpdate = time;
        clock.delta = clock.lastUpdate - getCurrentTimeUs();
    }

    public long getClock(Clock clock) {
        if (clock.lastUpdate == -1) {
            return 0;
        }
        if (mVideoState.status == VideoState.VideoStatus.START) {
            return getCurrentTimeUs() + clock.delta;
        }
        return clock.lastUpdate;
    }

    //获取主时钟
    public long getMainClock() {
        long currentClk = getClock(mVideoState.extClock);

        if (currentClk > mVideoState.durationUS) {
            setMainClock(mVideoState.durationUS);
            return mVideoState.durationUS;
        }
        return currentClk;
    }

    public void setMainClock(long time) {
        setClock(mVideoState.extClock, time);
    }

    public static AVEngine getVideoEngine() {
        if (gAVEngine == null) {
            synchronized (AVEngine.class) {
                if (gAVEngine == null) {
                    gAVEngine = new AVEngine();
                }
            }
        }
        return gAVEngine;
    }

    public void configure(SurfaceView glSurfaceView) {
        mSurfaceView = glSurfaceView;
        mRender.setSurface(glSurfaceView);
        mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback2() {
            @Override
            public void surfaceRedrawNeeded(@NonNull SurfaceHolder holder) {

            }

            @Override
            public void surfaceCreated(@NonNull SurfaceHolder holder) {
                AVEngine.this.surfaceCreated(holder.getSurface());
            }

            @Override
            public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
                AVEngine.this.surfaceChanged(holder, width, height);
            }

            @Override
            public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
                AVEngine.this.surfaceDestroyed(holder);
            }
        });
        mSurfaceView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                mSurfaceViewSize = new Size(mSurfaceView.getMeasuredWidth(), mSurfaceView.getMeasuredHeight());
                mSurfaceView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
        });
    }

    private Size calCanvasSize(String text, Size videoSize) {
        int width = mSurfaceViewSize.getWidth();
        int height = mSurfaceViewSize.getHeight();
        if (text.equalsIgnoreCase("原始")) {
            height = (int) (width * videoSize.getHeight() * 1.0f /
                    videoSize.getWidth());
            if (height > mSurfaceViewSize.getHeight()) {
                height = mSurfaceViewSize.getHeight();
                width = (int) (height * videoSize.getWidth() * 1.0f / videoSize.getHeight());
            }
        } else if (text.equalsIgnoreCase("4:3")) {
            height = (int) (width * 3.0f / 4.0f);
            if (height > mSurfaceViewSize.getHeight()) {
                height = mSurfaceViewSize.getHeight();
                width = (int) (height * 4.f / 3.f);
            }
        } else if (text.equalsIgnoreCase("3:4")) {
            width = (int) (height * 3.f / 4.0f);
        } else if (text.equalsIgnoreCase("1:1")) {
            width = height;
        } else if (text.equalsIgnoreCase("16:9")) {
            height = (int) (width * 9.0f / 16.0f);
            if (height > mSurfaceViewSize.getHeight()) {
                height = mSurfaceViewSize.getHeight();
                width = (int) (height * 16.f / 9.f);
            }
        } else if (text.equalsIgnoreCase("9:16")) {
            width = (int) (height * 9.0f / 16.0f);
        }
        return new Size(width, height);
    }

    /**
     * 设置画布大小
     */
    public void setCanvasType(String type, EngineCallback engineCallback) {
        if (type == null) return;
        if (mVideoState.videoComponents.isEmpty()) {
            return;
        }
        Size video0Size = ((IVideo) mVideoState.videoComponents.get(0)).getVideoSize();
        Size targetSize = calCanvasSize(type, video0Size);
        mSurfaceView.getLayoutParams().width = targetSize.getWidth();
        mSurfaceView.getLayoutParams().height = targetSize.getHeight();
        mSurfaceView.post(new Runnable() {
            @Override
            public void run() {
                mSurfaceView.requestLayout();
            }
        });
        mVideoState.lock();
        mVideoState.canvasType = type;
        mVideoState.canvasSize = targetSize;
        //   mVideoState.canvasMat = calMat(video0Size, mVideoState.canvasSize);
        //   mVideoState.compositeSize = MathUtils.calCompositeSize(mVideoState.canvasType, video0Size, mVideoState.compositeHeight);
        // mVideoState.compositeMat = calMat(video0Size, mVideoState.compositeSize);
        mVideoState.unlock();
        if (engineCallback != null) {
            engineCallback.onCallback(targetSize);
        }
    }

    /**
     * 设置背景颜色
     *
     * @param color
     */
    public void setBgColor(int color) {
        mVideoState.lock();
        mVideoState.bgColor = color;
        mVideoState.unlock();
        if (mVideoState.status == VideoState.VideoStatus.PAUSE) {
            fastSeek(getMainClock());
        }
    }

    public void updateEdit(AVComponent avComponent, boolean isEdit) {
        mVideoState.lock();
        mVideoState.isEdit = isEdit;
        mVideoState.editComponent = avComponent;
        mVideoState.unlock();
    }

    //return delay;
    //>=0代表延迟，已经渲染.
    //<0代表没有渲染。
    public long onDrawFrame() {
        if (!checkSeekAndReadyForRender()) {
            return 0;
        }
        renderVideo();
        renderScreen();//渲染到屏幕
        return renderForDelay();
    }

    private long renderForDelay() {
        boolean needRender = true;
        long delay = 0;
        long mainClock = getMainClock();
        long correctPts = getClock(mVideoState.videoClock);
        if (mVideoState.status == VideoState.VideoStatus.START) {
            delay = Math.max(correctPts - mainClock, 0);
            needRender = correctPts >= mainClock || delay < 50000;//这个阈值。。
        }
        //  LogUtil.logEngine("delay#" + delay);
        if (!needRender) {
            //  LogUtil.logEngine("needRender#delay#" + delay);
            return -1L;
        }
        if (delay > 0) {
            try {
                Thread.sleep(delay / 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return delay;
    }

    public void setOnFrameUpdateCallback(EngineCallback callback) {
        mUpdateCallback = callback;
    }

    //seek if need 同时返回是否需要render
    private boolean checkSeekAndReadyForRender() {
        if (mVideoState.status == VideoState.VideoStatus.RELEASE ||
                mVideoState.videoComponents.isEmpty()) {
            return false;
        }

        //获取相关组件
        long mainClk = mVideoState.drawClock = getMainClock();
        if (mainClk >= mVideoState.durationUS) {
            pauseInternal();
            return false;
        }

        mVideoState.drawVideoComponents.clear();
        List<AVComponent> trans = findComponents(AVComponent.AVComponentType.TRANSACTION, mainClk);
        for (AVComponent comm : trans) {
            if (comm.isVisible()) {
                mVideoState.drawVideoComponents.add(comm);
            }
        }
        if (mVideoState.drawVideoComponents.isEmpty()) {
            mVideoState.drawVideoComponents = findComponents(AVComponent.AVComponentType.VIDEO, mainClk);
        }
        if (mVideoState.drawVideoComponents.size() != 1) {//video transaction 在某个时间戳只存在一个组件
            // LogUtil.logEngine("videoComponents.size() != 1");
            return false;
        }

        boolean needSeek = mVideoState.videoClock.seekReq != mVideoState.videoClock.lastSeekReq;
        if (needSeek) {
            for (AVComponent component : mVideoState.drawPagComponents) {
                component.lock();
                component.seekFrame(mainClk);
                component.unlock();
            }
        }

        for (AVComponent component : mVideoState.drawVideoComponents) {
            component.lock();
            component.seekFrame(mainClk);
            component.unlock();
        }
        mVideoState.videoClock.lastSeekReq = mVideoState.videoClock.seekReq;
        return true;
    }

    private void renderVideo() {
        Log.i("TAGadf", "renderVideo: Ptssss:begin");
        AVComponent mainComponent = mVideoState.drawVideoComponents.get(0);
        AVFrame mainVideoFrame = mainComponent.peekFrame();
        if (!mainVideoFrame.isValid()) {

            return;
        }
        long correctPts = mainVideoFrame.getPts();

        mainVideoFrame.setTextColor(mVideoState.bgColor);

        SurfaceTexture texture = mainVideoFrame.getSurfaceTexture();
        videoDrawer.setVideoSize(mainVideoFrame.size().getWidth(),mainVideoFrame.size().getHeight());
        videoDrawer.setTextureID(mainVideoFrame.getTextureId());




       /* mOesRender.render(mainVideoFrame);
        lastTexture = mOesRender.getOutTexture();*/

       // lastTexture = mainComponent

        //如果是暂停状态，那么就保留，不是就mark read.
        if (mVideoState.status == VideoState.VideoStatus.START && !mainVideoFrame.isEof()) {
            mainVideoFrame.markRead();
        }
        Log.i("TAGadf", "renderVideo: Ptssss:");
        setClock(mVideoState.videoClock, correctPts);
        mLastVideoComponent = mainComponent;
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
        videoDrawer.draw();
        mEGLSurface.setTimesTamp(mainComponent.peekFrame().getPts());
        Log.i("TAGadf", "renderVideo: Pts:"+mainComponent.peekFrame().getPts());
        mEGLSurface.swapBuffers();
    }

    private void renderScreen() {
        //渲染到屏幕
        if (screenFrame == null) {
            screenFrame = new AVFrame();
        }
        //  screenFrame.setTexture(lastTexture);
        //  screenRender.write(TimeUtils.BuildMap("textureMat", mVideoState.canvasMat));
        //  screenRender.write(TimeUtils.BuildMap("bgColor", MathUtils.Int2Vec3(mVideoState.bgColor)));
        // screenRender.render(screenFrame);

    }


    private void createEngineDaemon() {
        ThreadManager.getInstance().createThread("EngineThread", () -> {
          /*  mEglHelper = new EglHelper();
            mEglHelper.create(null, EglHelper.GL_VERSION_3);
            mEglHelper.makeCurrent();*/

            mEGLSurface = new EGLSurfaceHolder();
            mEGLSurface.init(null, EGL_RECORDABLE_ANDROID);
            mEGLSurface.makeCurrent();

            //提前设置默认textureId 0默认值0x0
            GLES30.glBindTexture(GL_TEXTURE_2D, 0);
            GLES30.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
            mVideoState.reset();

            while (mVideoState.status != VideoState.VideoStatus.RELEASE) {
                while (true) {
                    Command command = mCmdQueue.poll();
                    Log.i("fsdfs", "createEngineDaemon: " + mCmdQueue.size());
                    if (command == null) break;
                    Log.i("TAGasf", "command: " + command.cmd);
                    if (command.cmd == Command.Cmd.SURFACE_CREATED) {
                    } else if (command.cmd == Command.Cmd.SURFACE_CHANGED) {
                        handleSurfaceChange(command);
                    } else if (command.cmd == Command.Cmd.SURFACE_DESTROYED) {
                        handleDestroy();
                    } else if (command.cmd == Command.Cmd.INIT) { //初始化完成
                        mVideoState.status = VideoState.VideoStatus.INIT;
                    } else if (command.cmd == Command.Cmd.PLAY) { //开始播放
                        Log.i("TAGasf", "createEngineDaemon:PLAY ");
                        playInternal();
                    } else if (command.cmd == Command.Cmd.PAUSE) { //暂停
                        pauseInternal();
                    } else if (command.cmd == Command.Cmd.RELEASE) { //销毁释放
                        destroyInternal();
                    } else if (command.cmd == Command.Cmd.SEEK) { //seekTo
                        handleSeek(command);

                    } else if (command.cmd == Command.Cmd.ADD_COM) { //添加视频源
                        Log.i("TAGasf", "createEngineDaemon:ADD_COM ");
                        handleAddComm(command);
                    } else if (command.cmd == Command.Cmd.REMOVE_COM) { //删除视频源
                        handleRemoveComm(command);
                    } else if (command.cmd == Command.Cmd.CHANGE_COM) { //修改视频源
                        handleChangeComm(command);
                    } else if (command.cmd == Command.Cmd.COMPOSITE) { //播放完成
                        pauseInternal();
                        handleDestroy();
                        mCompositeCallback = (EngineCallback) command.args0;
                    } else {

                    }
                }

                //开始处理视频
                boolean needRender = mVideoState.isSurfaceReady && (mVideoState.displaySwapCount < 1
                        || mVideoState.status == VideoState.VideoStatus.START);

                Log.i("TAGdfs", "createEngineDaemon: needRender:"+needRender);
                //开始渲染
                if (needRender) {
                    long delay = onDrawFrame();
                    Log.i("TAGdfs", "createEngineDaemon: delay:"+delay);
                    if (delay >= 0) {
                        //swap两次才能在屏幕显示...
                      //  mEglHelper.swap();
                        mVideoState.displaySwapCount++;
                        if (mVideoState.displaySwapCount == Long.MAX_VALUE) {
                            mVideoState.displaySwapCount = 1;
                        }
                    }
                } else {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                renderPostIfNeed();
            }
          //  mEglHelper.release();
        });
    }

    private EGLSurfaceHolder mEGLSurface;
    private VideoDrawer videoDrawer;
    private void handleSurfaceChange(Command command) {
        if (videoDrawer == null){
            videoDrawer = new VideoDrawer();
        }


       /* if (!mEglHelper.createSurface((Surface) command.args0)) {
            return;
        }
        if (!mEglHelper.makeCurrent()) {
            return;
        }*/
        //  if (mOesRender == null) {
          /*  mOesRender = new OESRender();
            mOesRender.open();
            screenRender = new ScreenRender();
            screenRender.open();*/
        // }
        int width = (int) command.args1;
        int height = (int) command.args2;
        videoDrawer.setWorldSize(width,height);
        Surface surface = (Surface)command.args0;
        mEGLSurface.createEGLSurface(surface,0,0);
      /*  mOesRender.write(TimeUtils.BuildMap("surface_size", new Size(width, height)));
        screenRender.write(TimeUtils.BuildMap("surface_size", new Size(width, height)));*/
        mVideoState.isSurfaceReady = true;



    }

    private void handleSeek(Command command) {
        long args = (long) command.args0;
        if (args == SEEK_EXIT && mVideoState.status == VideoState.VideoStatus.SEEK) {
            pauseInternal();
            return;
        }

        if (args == SEEK_ENTER) {//进入Seek模式
            mVideoState.status = VideoState.VideoStatus.SEEK;
            return;
        }

        if (mVideoState.status == VideoState.VideoStatus.SEEK) {
            long seekPositionUS = (long) command.args0;
            if (seekPositionUS < 0 || seekPositionUS > mVideoState.durationUS) {
                return;
            }
            mVideoState.isInputEOF = false;
            mVideoState.isOutputEOF = false;
            mVideoState.seekPositionUS = (long) command.args0;
            mVideoState.extClock.seekReq++;
            mVideoState.audioClock.seekReq = mVideoState.videoClock.seekReq = mVideoState.extClock.seekReq;
            mVideoState.displaySwapCount = 0;
            setMainClock(mVideoState.seekPositionUS);
        }
    }

    private void handleChangeComm(Command command) {
        AVComponent component = (AVComponent) command.args0;
        Map<String, Object> config = (Map<String, Object>) command.args1;
        component.lock();

        Rect src = (Rect) config.get("comm_src");
        Rect dst = (Rect) config.get("comm_dst");
        //裁剪操作的是file start/end time
        long duration = component.getClipDuration();
        float scale = duration * 1.0f / src.width();
        component.setClipStartTime(component.getClipStartTime() + (long) ((dst.left - src.left) * scale));
        component.setClipEndTime(component.getClipEndTime() - (long) ((src.right - dst.right) * scale));
        //重新设置EngineTime
        component.setEngineEndTime(component.getEngineStartTime() + component.getClipDuration());
        component.peekFrame().setValid(false);

        component.unlock();
        reCalculate();
        if (command.args2 != null) {
            EngineCallback callback = (EngineCallback) command.args2;
            callback.onCallback("");
        }
    }

    private void handleRemoveComm(Command command) {
        AVComponent component = (AVComponent) command.args0;
        component.lock();
        component.close();
        component.unlock();
        if (component.getType() == AVComponent.AVComponentType.AUDIO) {
            mVideoState.lock();
            mVideoState.audioComponents.remove(component);
            reCalculate();
            mVideoState.unlock();
        } else {
            mVideoState.lock();
            if (component instanceof AVVideo) {
                mVideoState.videoComponents.remove(component);
                reCalculate();
            } else {
                mVideoState.tranComponents.remove(component);
            }
            mVideoState.unlock();
        }
        if (command.args1 != null) {
            EngineCallback callback = (EngineCallback) command.args1;
            callback.onCallback("");
        }
    }

    private void handleAddComm(Command command) {
        AVComponent component = (AVComponent) command.args0;
        component.lock();
        if (component.getEngineStartTime() == -1) {
            component.setEngineStartTime(getMainClock());
        }
        //初始化解码器
        component.open();
        component.unlock();
/*
        if (component instanceof AVSticker || component instanceof AVWord || component instanceof AVPag) {
            component.setEngineEndTime(Math.min(component.getEngineEndTime(), getVideoState().durationUS));
        }*/
        //如果添加的是视频
        if (component instanceof AVVideo) {
            List<AVComponent> components = findComponents(AVComponent.AVComponentType.VIDEO, -1);
          /* if (!components.isEmpty()) {
                //获取视频
                AVVideo lastVideo = (AVVideo) components.get(components.size() - 1);
                AVTransaction avTransaction = new AVTransaction(
                        TimeUtils.leftTime(
                                TimeUtils.quzheng(lastVideo.getEngineEndTime())),//这里总是期待tran1 duration不小于1s
                        lastVideo,
                        (AVVideo) component,
                        new TransactionRender()
                );
                avTransaction.setVisible(false);
                avTransaction.open();
                mVideoState.tranComponents.add(avTransaction);
            }*/
       }
            Log.i("TAGhandleAddComm", "handleAddComm:component.getType():"+component.getType());

            if (component.getType() == AVComponent.AVComponentType.AUDIO) {
                mVideoState.lock();
                mVideoState.audioComponents.add(component);
                Log.i("TAGhandleAddComm", "handleAddComm: mVideoState.audioComponents:"+mVideoState.audioComponents.size());
                reCalculate();
                mVideoState.unlock();
            } else {
                mVideoState.lock();
                mVideoState.videoComponents.add(component);
                Log.i("TAGhandleAddCommvideo", "handleAddComm: mVideoState.videoComponents:"+mVideoState.videoComponents.size());

                reCalculate();
                mVideoState.unlock();
            }
            if (mVideoState.status == VideoState.VideoStatus.PAUSE) {
                fastSeek(getMainClock());
            }
            if (command.args1 != null) {
                EngineCallback callback = (EngineCallback) command.args1;
                callback.onCallback("");
            }
       // }
    }

    private void createAudioDaemon() {
        ThreadManager.getInstance().createThread("AudioThread", new Runnable() {
            @Override
            public void run() {

                while (mVideoState.status != VideoState.VideoStatus.RELEASE) {
                    Log.i("AFSD112s", "run: components---音频播放器初始化 state:"+mVideoState.status);
                    //只有运行时候才需要播放音频
                    if (mVideoState.status == VideoState.VideoStatus.START) {
                        long extClk = getMainClock();
                        Log.i("AFSD112s", "run: extClk:"+extClk+",:mVideoState.durationUS:"+mVideoState.durationUS);

                        if (extClk == mVideoState.durationUS) {
                            pause();
                            continue;
                        }
                        List<AVComponent> components = findComponents(AVComponent.AVComponentType.AUDIO, extClk);
                      //  Log.i("AFSD111121", "run: components" + components.get(0).getDuration());

                        if (components.isEmpty()) continue;
                        AVComponent audio = components.get(0);

                        if (!audio.isOpen()) continue;


                        audio.lock();
                        audio.seekFrame(extClk);
                        audio.unlock();
                        AVFrame audioFrame = audio.peekFrame();
                        if (!audioFrame.isValid()) {
                            continue;
                        }
                        if (Math.abs(audioFrame.getPts() - extClk) > 100000) {
                            audioFrame.markRead();//掉帧
                            continue;
                        }
                        setClock(mVideoState.audioClock, audioFrame.getPts());
                        audioFrame.markRead();
                        mLastAudioComponent = audio;
                    } else {
                        try {
                            Thread.sleep(PLAY_GAP);//TODO
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
    }

    /**
     * 根据类型，时间组合查找组件
     *
     * @param type     ALL默认通过
     * @param position -1默认通过
     * @return 目标组件
     */
    public List<AVComponent> findComponents(AVComponent.AVComponentType type, long position) {
       Log.i("AFSD1111findComponents", "run: components findComponents:"+mVideoState.audioComponents+",type:"+type);
        List<AVComponent> mTargetComponents = new LinkedList<>();
        mTargetComponents.clear();

        //当前类型是音频
        if (type == AVComponent.AVComponentType.AUDIO) {
            mVideoState.lock();

            for (AVComponent component : mVideoState.audioComponents) {
             //   Log.i("AFSD1111findComponents", "findComponentsisValid:"+component.isValid(position)+",type:"+component.getType());
                if ((component.getType() == type && (position == -1 || component.isValid(position)))) {
                    mTargetComponents.add(component);
                }
            }
            mVideoState.unlock();
        } else {
            mVideoState.lock();
            for (AVComponent component : type == AVComponent.AVComponentType.TRANSACTION ? mVideoState.tranComponents : mVideoState.videoComponents) {
                if (type == AVComponent.AVComponentType.ALL || (component.getType() == type &&
                        (position == -1 || component.isValid(position)))) {
                    mTargetComponents.add(component);
                }
            }
            mVideoState.unlock();
        }
        return mTargetComponents;
    }

    /**
     * 添加组件
     *
     * @param avComponent
     */
    public void addComponent(AVComponent avComponent, EngineCallback engineCallback) {
        Command command = new Command();
        command.cmd = Command.Cmd.ADD_COM;
        command.args0 = avComponent;
        command.args1 = engineCallback;
        mCmdQueue.add(command);
    }

    /**
     * 修改组件时间信息
     *
     * @param avComponent    目标组件
     * @param config         设置
     * @param engineCallback 回调
     */
    public void changeComponent(AVComponent avComponent, Map<String, Object> config, EngineCallback
            engineCallback) {
        Command command = new Command();
        command.cmd = Command.Cmd.CHANGE_COM;
        command.args0 = avComponent;
        command.args1 = config;
        command.args2 = engineCallback;
        mCmdQueue.add(command);
    }

    /**
     * 删除组件
     *
     * @param avComponent
     */
    public void removeComponent(AVComponent avComponent) {
        Command command = new Command();
        command.cmd = Command.Cmd.REMOVE_COM;
        command.args0 = avComponent;
        mCmdQueue.add(command);
    }

    /**
     * 计算总时长US.
     */
    private void reCalculate() {
        mVideoState.videoDuration = mVideoState.audioDuration = 0;
        for (AVComponent component : mVideoState.videoComponents) {
            mVideoState.videoDuration = Math.max(component.getEngineEndTime(), mVideoState.videoDuration);
        }
        for (AVComponent component : mVideoState.audioComponents) {
            if (component instanceof AVAudio) {
                mVideoState.audioDuration = Math.max(component.getEngineEndTime(), mVideoState.audioDuration);
            }
        }
        mVideoState.durationUS = mVideoState.videoDuration;
        if (getMainClock() > mVideoState.durationUS) {
            setMainClock(mVideoState.durationUS);
        }
    }

    public void surfaceCreated(Surface surface) {
        Command command = new Command();
        command.cmd = Command.Cmd.SURFACE_CREATED;
        mCmdQueue.add(command);
    }

    public void surfaceChanged(SurfaceHolder holder, int width, int height) {
        Command command = new Command();
        command.cmd = Command.Cmd.SURFACE_CHANGED;
        command.args0 = holder.getSurface();
        command.args1 = width;
        command.args2 = height;
        mCmdQueue.add(command);
        //同步等待Engine线程处理完surface
        while (!mVideoState.isSurfaceReady) {
            try {
                Thread.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        fastSeek(0);
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        Command command = new Command();
        command.cmd = Command.Cmd.SURFACE_DESTROYED;
        mCmdQueue.add(command);
        //同步等待Engine线程处理完surface
        while (mVideoState.isSurfaceReady) {
            try {
                Thread.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void start() {
        Command command = new Command();
        command.cmd = Command.Cmd.PLAY;
        mCmdQueue.add(command);
    }

    private void playInternal() {
        setClock(mVideoState.extClock, getClock(mVideoState.extClock));
        mVideoState.status = VideoState.VideoStatus.START;
    }

    private void handleDestroy() {
       // mEglHelper.destroySurface();
      //  mEglHelper.makeCurrent();
           /* if (mOesRender != null) {
                mOesRender.close();
                mOesRender = null;
            }*/

        mVideoState.isSurfaceReady = false;
    }

    public void pause() {
        Command command = new Command();
        command.cmd = Command.Cmd.PAUSE;
        mCmdQueue.add(command);
    }

    private void pauseInternal() {
        setMainClock(getMainClock());
        mVideoState.status = VideoState.VideoStatus.PAUSE;
    }

    public void togglePlayPause() {
        if (mVideoState.status == VideoState.VideoStatus.START) {
            pause();
        } else {
            start();
        }
    }

    private static final int SEEK_ENTER = -1;
    private static final int SEEK_EXIT = -2;

    /**
     * SEEK部分
     * fastSeek用于快速seek某个位置，自动进退seek模式
     * seek(true)进入seek模式
     * seek(false)退出seek模式
     */
    public void fastSeek(long position) {
        seek(true);
        seek(position);
        seek(false);
    }

    public void seek(long position) {
        Command command = new Command();
        command.cmd = Command.Cmd.SEEK;
        command.args0 = position;
        mCmdQueue.add(command);
    }

    public void seek(boolean status) {
        Command command = new Command();
        command.cmd = Command.Cmd.SEEK;
        command.args0 = (long) (status ? SEEK_ENTER : SEEK_EXIT);
        mCmdQueue.add(command);
    }

    public void create() {
        createEngineDaemon();
        createAudioDaemon();
    }

    private void releaseInternal() {
        Command command = new Command();
        command.cmd = Command.Cmd.RELEASE;
        mCmdQueue.offer(command);
    }

    public void release() {
        releaseInternal();
        ThreadManager.getInstance().destroyThread("AudioThread");
        ThreadManager.getInstance().destroyThread("EngineThread");
//        AVEngine.gAVEngine = null;//...貌似不是很合适。。TODO
    }

    private void destroyInternal() {
        mVideoState.status = VideoState.VideoStatus.RELEASE;
        mVideoState.lock();
        for (AVComponent avComponent : mVideoState.audioComponents) {
            avComponent.lock();
            avComponent.close();
            avComponent.unlock();
        }
        mVideoState.audioComponents.clear();

        for (AVComponent avComponent : mVideoState.videoComponents) {
            avComponent.lock();
            avComponent.close();
            avComponent.unlock();
        }
        mVideoState.videoComponents.clear();
        mVideoState.unlock();
    }

    public VideoState getVideoState() {
        return mVideoState;
    }

  /*  public EglHelper getEglHelper() {
        return mEglHelper;
    }*/

    private void renderPostIfNeed() {
        if (mUpdateCallback != null) {
            mUpdateCallback.onCallback("");
        }
    }

    private Map<String, Object> mConfigs = new HashMap<>();

    private Map<String, Object> buildConfig(Object... args) {
        if (args.length % 2 != 0) {
            return null;
        }
        for (int i = 0; i < args.length / 2; i++) {
            mConfigs.put((String) args[2 * i], args[2 * i + 1]);
        }
        return mConfigs;
    }

    private void dumpVideoState() {
//        LogUtil.logEngine(mVideoState.toString());
    }

}
